#region Copyright (c) 2006-2012 nHydrate.org, All Rights Reserved
//--------------------------------------------------------------------- *
//                          NHYDRATE.ORG                                *
//             Copyright (c) 2006-2012 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF THE NHYDRATE GROUP *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS THIS PRODUCT                 *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF NHYDRATE,          *
//THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO             *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using nHydrate.Generator.Common.GeneratorFramework;
using nHydrate.Generator.Models;
using nHydrate.Generator.ProjectItemGenerators;
using nHydrate.Generator.Common.Util;
using nHydrate.Generator.SQLInstaller;
using nHydrate.Generator.Common.EventArgs;
using System.IO;

namespace nHydrate.Generator.SQLInstaller.ProjectItemGenerators.DatabaseEmbeddedClasses
{
	[GeneratorItemAttribute("DatabaseEmbeddedClassGenerator", typeof(DatabaseProjectGenerator))]
	public class DatabaseEmbeddedClassGenerator : BaseDbScriptGenerator
	{
		private const string EMBEDDED_LOCATION = "ProjectItemGenerators.DatabaseEmbeddedClasses";

		#region Overrides
		public override int FileCount
		{
			get { return 22; }
		}

		public override void Generate()
		{
			try
			{
				GenerateDatabaseInstallerCs();
				GenerateAzureCopy();
				GenerateInstallSettings();
				GenerateDatabaseInstallerDesignerCs();
				GenerateIdentifyDatabaseFormCs();
				GenerateIdentifyDatabaseFormDesigner();
				GenerateIdentifyDatabaseFormResx();
				GenerateHistoryFormCs();
				GenerateHistoryFormResx();
				GenerateSqlServersCs();
				//GenerateArchiveReaderCs();
				GenerateXmlHelperCs();
				GenerateUpgradeInstaller();
				GenerateAzureCopyControlCs();
				GenerateAzureCopyControlDesigner();
				GenerateAzureCopyControlResx();

				//Folder structure
				GenerateFolder1();
				GenerateFolder2();
				GenerateFolder3();
				GenerateFolder4();
				GenerateFolder5();
				GenerateFolder6();

				var gcEventArgs = new ProjectItemGenerationCompleteEventArgs(this);
				OnGenerationComplete(this, gcEventArgs);

				_model.IncrementGeneratedVersion();
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		private void GenerateFolder1()
		{
			var foldername = "1_UserDefinedInitialization";
			var fileName = string.Empty;
			ProjectItemGeneratedEventArgs eventArgs = null;

			//Main folder Readme.txt
			fileName = Path.Combine(foldername, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, GetTextFolder1ReadMe(), ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Create Always
			var folderAlways = Path.Combine(foldername, "Always");
			fileName = Path.Combine(folderAlways, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will always run first in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//New Database
			var folderNewDatabase = Path.Combine(foldername, "NewDatabase");
			fileName = Path.Combine(folderNewDatabase, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run first on a database creation in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Unversioned
			var folderUnversioned = Path.Combine(foldername, "UnVersioned");
			fileName = Path.Combine(folderUnversioned, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run first on an existing non-versioned database in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Versioned
			var folderVersioned = Path.Combine(foldername, "Versioned");
			fileName = Path.Combine(folderVersioned, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run first on an existing versioned database in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

		}

		private void GenerateFolder2()
		{
			var foldername = "2_Upgrade Scripts";
			var fileName = string.Empty;
			ProjectItemGeneratedEventArgs eventArgs = null;

			fileName = Path.Combine(foldername, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Scripts in this folder are generated once and can be modified by the user after generation.\return\nEverything under this folder will be run in version number order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateFolder3()
		{
			var foldername = "3_GeneratedTablesAndData";
			var fileName = string.Empty;
			ProjectItemGeneratedEventArgs eventArgs = null;

			fileName = Path.Combine(foldername, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Do not modify scripts in this folder.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

		}

		private void GenerateFolder4()
		{
			var foldername = "4_UserDefinedPostTablesAndData";
			var fileName = string.Empty;
			ProjectItemGeneratedEventArgs eventArgs = null;

			//Main folder Readme.txt
			fileName = Path.Combine(foldername, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, GetTextFolder4ReadMe(), ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Create Always
			var folderAlways = Path.Combine(foldername, "Always");
			fileName = Path.Combine(folderAlways, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will always run after schema and upgrades in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//New Database
			var folderNewDatabase = Path.Combine(foldername, "NewDatabase");
			fileName = Path.Combine(folderNewDatabase, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run after schema and upgrades on a database creation in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Unversioned
			var folderUnversioned = Path.Combine(foldername, "UnVersioned");
			fileName = Path.Combine(folderUnversioned, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run after schema and upgrades on an existing non-versioned database in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Versioned
			var folderVersioned = Path.Combine(foldername, "Versioned");
			fileName = Path.Combine(folderVersioned, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run after schema and upgrades on an existing versioned database in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

		}

		private void GenerateFolder5()
		{
			var foldername = "5_Programmability";
			var fileName = string.Empty;
			ProjectItemGeneratedEventArgs eventArgs = null;

			//User-defined Functions
			var folderUD = Path.Combine(Path.Combine(foldername, "Functions"), "User Defined");
			fileName = Path.Combine(folderUD, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add user-defined scripts for database functions in this folder.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//User-defined Stored Procedures
			folderUD = Path.Combine(Path.Combine(foldername, "Stored Procedures"), "User Defined");
			fileName = Path.Combine(folderUD, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add user-defined scripts for database stored procedures in this folder.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//User-defined Views
			folderUD = Path.Combine(Path.Combine(foldername, "Views"), "User Defined");
			fileName = Path.Combine(folderUD, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add user-defined scripts for database views in this folder.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

		}

		private void GenerateFolder6()
		{
			var foldername = "6_UserDefinedFinalize";
			var fileName = string.Empty;
			ProjectItemGeneratedEventArgs eventArgs = null;

			//Main folder Readme.txt
			fileName = Path.Combine(foldername, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, GetTextFolder4ReadMe(), ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Create Always
			var folderAlways = Path.Combine(foldername, "Always");
			fileName = Path.Combine(folderAlways, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will always run after all other scripts in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//New Database
			var folderNewDatabase = Path.Combine(foldername, "NewDatabase");
			fileName = Path.Combine(folderNewDatabase, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run after all other scripts on a database creation in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Unversioned
			var folderUnversioned = Path.Combine(foldername, "UnVersioned");
			fileName = Path.Combine(folderUnversioned, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run after all other scripts on an existing non-versioned database in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

			//Versioned
			var folderVersioned = Path.Combine(foldername, "Versioned");
			fileName = Path.Combine(folderVersioned, "ReadMe.txt");
			eventArgs = new ProjectItemGeneratedEventArgs(fileName, "Add scripts that will be run after all other scripts on an existing versioned database in this folder. Make them embedded resources and they will be run in alphabetical order.", ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);

		}

		private string GetTextFolder1ReadMe()
		{
			var sb = new StringBuilder();
			sb.AppendLine("Please place any custom scripts that need to run prior to all generated scripts here. Make sure they are an embedded resource");
			sb.AppendLine();
			sb.AppendLine("There are three ways that a database install happens:");
			sb.AppendLine("\"NewDatabase\" Folder - During the process of installation the user chooses to create a new database. ");
			sb.AppendLine("\"Unversioned\" Folder - During the process of installation the user chooses to upgrade a database that has not been versioned by nHydrate");
			sb.AppendLine("\"Versioned\" Folder - During the process of installation the user chooses to upgrade a database that has been versioned by nHydrate");
			sb.AppendLine("\"Always\" Folder: After the scenario specific scripts have run. Scripts in the \"Always\" folder will be run regardless of scenario.");
			sb.AppendLine();
			sb.AppendLine("For each specific folder custom scripts are run in Alphabetical order. For this reason it is best practice to use a number based prefix as part of your naming standard example:");
			sb.AppendLine("000_Always");
			sb.AppendLine("001_Always");
			sb.AppendLine("002_Always");
			sb.AppendLine("::::::::");
			sb.AppendLine("999_Always");
			return sb.ToString();
		}

		private string GetTextFolder4ReadMe()
		{
			var sb = new StringBuilder();
			sb.AppendLine("Please place any custom scripts that need to run after the generated schema and data files have been run.  Make sure they are an embedded resource.");
			sb.AppendLine();
			sb.AppendLine("There are three ways that an db install happens:");
			sb.AppendLine("\"NewDatabase\" Folder - During the process of installation the user chooses to create a new database. ");
			sb.AppendLine("\"Unversioned\" Folder - During the process of installation the user chooses to upgrade a database that has not been versioned by nHydrate");
			sb.AppendLine("\"Versioned\" Folder - During the process of installation the user chooses to upgrade a database that has been versioned by nHydrate");
			sb.AppendLine("\"Always\" Folder: After the scenario specific scripts have run. Scripts in the \"Always\" folder will be run regardless of scenario.");
			sb.AppendLine();
			sb.AppendLine("For each specific folder custom scripts are run in Alphabetical order. For this reason it is best practice to use a number ");
			sb.AppendLine("based prefix as part of your naming standard example:");
			sb.AppendLine("000_Always");
			sb.AppendLine("001_Always");
			sb.AppendLine("002_Always");
			sb.AppendLine("::::::::");
			sb.AppendLine("999_Always");
			return sb.ToString();
		}

		private string GetTextFolder6ReadMe()
		{
			var sb = new StringBuilder();
			sb.AppendLine("Please place any custom scripts that need to run after everything else here. Make sure they are an embedded resource.");
			sb.AppendLine();
			sb.AppendLine("There are three ways that an db install happens:");
			sb.AppendLine("\"NewDatabase\" Folder - During the process of installation the user chooses to create a new database. ");
			sb.AppendLine("\"Unversioned\" Folder - During the process of installation the user chooses to upgrade a database that has not been versioned by nHydrate");
			sb.AppendLine("\"Versioned\" Folder - During the process of installation the user chooses to upgrade a database that has been versioned by nHydrate");
			sb.AppendLine("\"Always\" Folder: After the scenario specific scripts have run. Scripts in the \"Always\" folder will be run regardless of scenario.");
			sb.AppendLine();
			sb.AppendLine("For each specific folder custom scripts are run in Alphabetical order. For this reason it is best practice to use a number ");
			sb.AppendLine("based prefix as part of your naming standard example:");
			sb.AppendLine("000_Always");
			sb.AppendLine("001_Always");
			sb.AppendLine("002_Always");
			sb.AppendLine("::::::::");
			sb.AppendLine("999_Always");
			return sb.ToString();
		}



		private void GenerateIdentifyDatabaseFormCs()
		{
			var fileName = "IdentifyDatabaseForm.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateIdentifyDatabaseFormResx()
		{
			var fullParentName = "IdentifyDatabaseForm.cs";
			var fileName = "IdentifyDatabaseForm.resx";
			var ern = new EmbeddedResourceName();
			ern.AsmLocation = this.GetEmbeddedPath();
			ern.FileName = fileName + ".embed";
			ern.FullName = this.GetEmbeddedPath() + "." + ern.FileName;
			var fileContent = GetFileContent(ern);
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, fullParentName, this, true);
			eventArgs.Properties.Add("BuildAction", 3);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateIdentifyDatabaseFormDesigner()
		{
			var fullParentName = "IdentifyDatabaseForm.cs";
			var fileName = "IdentifyDatabaseForm.Designer.cs";
			var ern = new EmbeddedResourceName();
			ern.AsmLocation = this.GetEmbeddedPath();
			ern.FileName = "IdentifyDatabaseForm.Designer.embed";
			ern.FullName = this.GetEmbeddedPath() + "." + ern.FileName;
			var fileContent = GetFileContent(ern);
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, fullParentName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateAzureCopyControlCs()
		{
			var fileName = "AzureCopyControl.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateAzureCopyControlResx()
		{
			var fullParentName = "AzureCopyControl.cs";
			var fileName = "AzureCopyControl.resx";
			var ern = new EmbeddedResourceName();
			ern.AsmLocation = this.GetEmbeddedPath();
			ern.FileName = fileName + ".embed";
			ern.FullName = this.GetEmbeddedPath() + "." + ern.FileName;
			var fileContent = GetFileContent(ern);
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, fullParentName, this, true);
			eventArgs.Properties.Add("BuildAction", 3);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateAzureCopyControlDesigner()
		{
			var fullParentName = "AzureCopyControl.cs";
			var fileName = "AzureCopyControl.Designer.cs";
			var ern = new EmbeddedResourceName();
			ern.AsmLocation = this.GetEmbeddedPath();
			ern.FileName = "AzureCopyControl.Designer.embed";
			ern.FullName = this.GetEmbeddedPath() + "." + ern.FileName;
			var fileContent = GetFileContent(ern);
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, fullParentName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateHistoryFormResx()
		{
			var fullParentName = "HistoryForm.cs";
			var fileName = "HistoryForm.resx";
			var ern = new EmbeddedResourceName();
			ern.AsmLocation = this.GetEmbeddedPath();
			ern.FileName = fileName + ".embed";
			ern.FullName = this.GetEmbeddedPath() + "." + ern.FileName;
			var fileContent = GetFileContent(ern);
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, fullParentName, this, true);
			eventArgs.Properties.Add("BuildAction", 3);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateUpgradeInstaller()
		{
			var fileName = "UpgradeInstaller.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			//TODO - Change the version for _upgradeToVersion and _previousVersion
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateSqlServersCs()
		{
			var fileName = "SqlServers.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		//private void GenerateArchiveReaderCs()
		//{
		//  var fileName = "ArchiveReader.cs";
		//  var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
		//  var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
		//  OnProjectItemGenerated(this, eventArgs);
		//}

		private void GenerateXmlHelperCs()
		{
			var fileName = "XmlHelper.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateHistoryFormCs()
		{
			var fileName = "HistoryForm.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateDatabaseInstallerDesignerCs()
		{
			var fullParentName = "DatabaseInstaller.cs";
			var fileName = "DatabaseInstaller.Designer.cs";
			var ern = new EmbeddedResourceName();
			ern.AsmLocation = this.GetEmbeddedPath();
			ern.FileName = "DatabaseInstaller.Designer.embed";
			ern.FullName = this.GetEmbeddedPath() + "." + ern.FileName;
			var fileContent = GetFileContent(ern);
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, fullParentName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateDatabaseInstallerCs()
		{
			var fileName = "DatabaseInstaller.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateAzureCopy()
		{
			var fileName = "AzureCopy.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private void GenerateInstallSettings()
		{
			var fileName = "InstallSettings.cs";
			var fileContent = GetFileContent(new EmbeddedResourceName(this.GetEmbeddedPath() + "." + fileName));
			var eventArgs = new ProjectItemGeneratedEventArgs(fileName, fileContent, ProjectName, this, true);
			OnProjectItemGenerated(this, eventArgs);
		}

		private string GetResource(EmbeddedResourceName ern)
		{
			var retVal = string.Empty;
			var asm = Assembly.GetExecutingAssembly();
			var manifestStream = asm.GetManifestResourceStream(ern.FullName);
			try
			{
				using (var sr = new System.IO.StreamReader(manifestStream))
				{
					retVal = sr.ReadToEnd();
				}
			}
			catch { }
			finally
			{
				manifestStream.Close();
			}
			return retVal;
		}

		private string GetFileContent(EmbeddedResourceName ern)
		{
			try
			{
				string retVal = GetResource(ern);
				retVal = ReplaceNHydrateSpecifics(retVal);
				return retVal;
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		private string ReplaceNHydrateSpecifics(string input)
		{
			var retVal = input;
			retVal = retVal.Replace("WS", _model.CompanyAbbreviation);
			retVal = retVal.Replace("Acme", _model.CompanyName);
			retVal = retVal.Replace("%MODELKEY%", _model.Key);
			retVal = retVal.Replace("%COLLATE%", _model.Database.Collate);
			retVal = retVal.Replace("ZZ", _model.CompanyAbbreviation);
			var versionNumbers = _model.Version.Split('.');
			
			int major = int.Parse(versionNumbers[0]);
			var minor = int.Parse(versionNumbers[1]);
			var revision = int.Parse(versionNumbers[2]);
			var build = int.Parse(versionNumbers[3]);
			var generated = _model.GetGeneratedVersion();

			retVal = retVal.Replace("\"UPGRADE_VERSION\"", major + ", " + minor + ", " + revision + ", " + build + ", " + generated);
			retVal = retVal.Replace("DATABASENAME", _model.Database.DatabaseName);
			retVal = retVal.Replace("PROJECTNAMESPACE", this.GetLocalNamespace());			
			retVal = retVal.Replace("DATABASETYPE", _model.SQLServerType.ToString());
			return retVal;
		}

		private string GetEmbeddedPath()
		{
			return System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + "." + EMBEDDED_LOCATION;
		}

		#endregion

	}
}